#pragma once

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>



//序列化和反序列化有很多工具可以实现:jsoncpp 和 protobuf

const std::string Sep = "\r\n";



//{json} -> len\r\n{json}\r\n
bool Encode(std::string& message)
{
    //添加报头,在前面添加  长度\n
    if(message.size() == 0)
    {
        return false;
    }
    std::string package = std::to_string(message.size())+Sep+message+Sep;
    message = package;
    return true;
}


//操作系统只管发消息,不维护消息的完整性
//维护消息的完整性,要应用层做
//len\r\n{json}\r\n -> {json}
bool Decode(std::string& package,std::string* content)
{
    auto pos = package.find(Sep);
    if(pos == std::string::npos)
    {
        return false;
    }
    std::string content_length_str = package.substr(0,pos);
    int content_length = std::stoi(content_length_str);
    //判断报文是否是完整的
    int full_length = content_length_str.size() + content_length + 2*Sep.size();
    if(package.size() < full_length)
    {
        return false;
    }
    *content = package.substr(pos+Sep.size(),content_length);//有效载荷的内容
    package.erase(0,full_length);//后续写网络代码再说
    
    return true;
}


//_x _oper _y
class Request
{
public:
    Request():_x(0),_y(0),_oper(0)
    {

    }

    Request(int x,int y,char oper):_x(x),_y(y),_oper(oper)
    {

    }

    bool Serialize(std::string& out_string)//序列化
    {
        //jsoncpp:自定义  ->   字符串
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root,&ss);
        out_string = ss.str();

        return true;
    }

    bool Deserialize(std::string& in_string)//反序列化
    {
        Json::Value root;
        Json::Reader reader;
        //in_string 转 root
        bool paesingSuccessful = reader.parse(in_string,root);

        if(!paesingSuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() <<std::endl;
            return false;
        }

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();//char类型的ASCLL码值

        return true;
    }

    void Print()
    {
        std::cout << _x<<std::endl;
        std::cout << _y<<std::endl;
        std::cout << _oper<<std::endl;
    }

    int X()const
    {
        return _x;
    }

    int Y()const
    {
        return _y;
    }

    char Oper()const
    {
        return _oper;
    }

private:
    int _x;
    int _y;
    char _oper;
};




class Response
{
public:
    Response():_result(0),_code(0)
    {

    }

    Response(int result,int code):_result(result),_code(code)
    {

    }

    bool Serialize(std::string& out_string)//序列化
    {
        //jsoncpp:自定义  ->   字符串
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root,&ss);
        out_string = ss.str();

        return true;
    }

    bool Deserialize(std::string& in_string)//反序列化
    {
        Json::Value root;
        Json::Reader reader;
        //in_string 转 root
        bool paesingSuccessful = reader.parse(in_string,root);

        if(!paesingSuccessful)
        {
            std::cout << "Failed to parse JSON: "<<reader.getFormattedErrorMessages()<<std::endl;
            return false;
        }

        _result = root["result"].asInt();
        _code = root["code"].asInt();

        return true;
    }

    int Result()const
    {
        return _result;
    }

    int Code()const
    {
        return _code;
    }

    void SetResult(int res)
    {
        _result = res;
    }

    void SetCode(int c)
    {
        _code = c;
    }

private:
    int _result;//结果
    int _code;  //结果出错码   (0,1,2,3,4)
};




